from django import forms
from django.forms import ModelForm, BaseModelForm
from hosting.domains.models import SOA, RR
from django.forms.widgets import TextInput, Textarea, HiddenInput
import re
from datetime import datetime

class SOAForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(SOAForm, self).__init__(*args, **kwargs)

        # change a widget attribute:
        self.fields['ns'].widget.attrs["size"] = 15
        self.fields['mbox'].widget.attrs["size"] = 15
        self.fields['serial'].widget.attrs["size"] = 15
        self.fields['serial'].widget.attrs["maxlength"] = 12
        self.fields['refresh'].widget.attrs["size"] = 15
        self.fields['retry'].widget.attrs["size"] = 15
        self.fields['expire'].widget.attrs["size"] = 15
        self.fields['minimum'].widget.attrs["size"] = 15
        self.fields['ttl'].widget.attrs["size"] = 15
        self.fields['ttl'].widget.attrs["maxlength"] = 11

    class Meta:
        model = SOA
        exclude = ('user', 'origin', 'active') 

    def clean_serial(self):
        min_serial = int(datetime.strftime(datetime.now(), "%Y%m%d")+'00')
        max_serial = min_serial+100
        data = self.cleaned_data["serial"]
        if data < min_serial: data = min_serial
        if data > max_serial: data = max_serial
        return data

    def clean_refresh(self):
        data = self.cleaned_data["refresh"]
        if data >= 604800000: data = 604800000
        if data <= 0: data = 86400
        return data

    def clean_ttl(self):
        data = self.cleaned_data["ttl"]
        if data >= 604800000: data = 604800000
        if data <= 0: data = 86400
        return data

    def clean_retry(self):
        data = self.cleaned_data["retry"]
        if data >= 604800000: data = 604800000
        if data <= 0: data = 14400
        return data

    def clean_expire(self):
        data = self.cleaned_data["expire"]
        if data >= 604800000: data = 604800000
        if data <= 0: data = 2592000
        return data

    def clean_minimum(self):
        data = self.cleaned_data["minimum"]
        if data >= 604800000: data = 604800000
        if data <= 0: data = 345600
        return data

class RRForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(RRForm, self).__init__(*args, **kwargs)

        # change a widget attribute:
        self.fields['zone'].widget = HiddenInput()
        self.fields['name'].widget.attrs["size"] = 15
        self.fields['data'].widget.attrs["size"] = 18
        self.fields['aux'].widget.attrs["size"] = 3
        self.fields['ttl'].widget.attrs["size"] = 6

    class Meta:
        model = RR
#        exclude = ('zone',) 

    def clean(self):
        cleaned_data = self.cleaned_data
        data = cleaned_data.get("data")
        type = cleaned_data.get("type")
        name = cleaned_data.get("name")
        aux = cleaned_data.get("aux")
        ttl = cleaned_data.get("ttl")
        if data == None:
            data = '@'
        if name == None:
            name = '@'

        if type in ('A', 'CNAME', 'NS', 'MX', 'CNAME', 'AAAA'):
            data = data.lower()
            name = name.lower()
            data = re.sub('\.+', '.', data)
            name = re.sub('\.+', '.', name)
            not_valid = re.compile('[^a-z0-9\.-]+')
            if name != '@':
                name = re.sub(not_valid, '', name)
            if type in ('NS', 'MX', 'CNAME'):
                data = re.sub(not_valid, '', data)
            elif type == 'A':
                data = re.sub('[^0-9\.]+', '', data)
            elif type == 'AAAA':
                data = re.sub('[^0-9a-f:]+', '', data)

        if not type in ('SRV', 'MX'):
            aux = 0
        else:
            if aux <= 0:
                aux = 0
            elif aux >= 65535:
                aux = 65535
            if type == 'SRV':
                data = re.sub('\s+$', '', data)
                data = re.sub('^\s+', '', data)
                try:
                    (weight, port, target) = re.split('\s+', data, maxsplit=2)
                except:
                    target = data
                try:
                    port = int(port)
                    if port > 65535: port = 65535
                    if port < 0: port = 0
                except:
                    port = 0
                try:
                    weight = int(weight)
                    if weight > 999: weight = 999
                    if weight < 0: weight = 0
                except:
                    weight = 0
                if target != '@':
                    target = target.lower()
                    target = re.sub('\.+', '.', target)
                    target = re.sub('[^a-z0-9\.-]+', '', target)
                    if target == '': target = '@'
                data = '%s %s %s' % (weight, port, target)

        if ttl > 604800000:
            ttl = 604800000
        elif ttl <= 0:
            ttl = 86400

        if name == '': name = '@'
        if data == '': data = '@'
        cleaned_data['aux'] = aux
        cleaned_data['ttl'] = ttl
        cleaned_data['name'] = name
        cleaned_data['data'] = data

        return cleaned_data

